#include <stdio.h>
#include <string.h>
#include <unistd.h>

#include <slothttpd/ngx_parser/ngx_parser.hpp>


static char request[] = 
"GET http://www.myhost.org:1234/index.html%20%20?key1=value1key2=value2#fragm HTTP/1.1\n"
"Host: myhost.org\n"
"\n";

static char *segmented_request[] = {
        "GET /",
        "index.html HTTP/",
        "1.1\nHost: myhost.org\n\n",
};


void wr(const char *s, char *first, char *last)
{
        if (first == NULL) {
                printf("NULL\n");
                return;
        }
        printf(s);
        fflush(stdout);
        write(STDOUT_FILENO, first, last - first);
        fflush(stdout);
        puts("");
}

void test_full(void)
{
        u_char *start = request;
        u_char *end   = request + strlen(request);
        
        ngx_buf_t buf = (ngx_buf_t) {
                .pos = start,
                .last = end,
        };
        
        ngx_http_request_t req;
        memset(&req, 0, sizeof req);
        
        ngx_int_t r = ngx_http_parse_request_line(&req, &buf);
        
        printf("buf: %p, %p\n", buf.pos, buf.last);
        printf("buf pos: %s\n", buf.pos);
        printf("buf last: %s\n", buf.last);
        
        printf("%d\n", r);
        
        wr("method: ", request, req.method_end + 1);
        wr("uri: ", req.uri_start, req.uri_end);
        
        printf("HTTP/%d.%d\n", req.http_version / 1000, req.http_version % 1000);
        
        printf("quoted: %d\n", req.quoted_uri);
        
        static char unescaped[1000];
        
        memset(unescaped, 0xFF, sizeof unescaped);
        
        u_char *p = unescaped;
        start   = req.uri_start;
        end     = start;
        
        /*
        printf("%p, %p\n", start, end);
        ngx_unescape_uri(&p, &start, end - start, 0);
        printf("%p\n", start);
        
        printf("%p\n", p);
        
        printf("%s\n", unescaped);
        */
        
        ngx_unescape_uri(&start, &end, req.uri_end - req.uri_start, 0);
        wr("uri: ", req.uri_start, end);
        u_char *path_first = req.uri_start;
        u_char *path_last  = strchr(req.uri_start, '?');
        
        wr("path: ", path_first, path_last);
        {
                u_char *start = request;
                u_char *end   = request + strlen(request);
                wr("args_start: ", req.args_start, end);
        }
}

void test_seg(void)
{
        ngx_http_request_t req;
        memset(&req, 0, sizeof req);
        
        for (int i = 0; i < 3; i++) {
                char *seg = segmented_request[i];
                
                u_char *start = seg;
                u_char *end   = seg + strlen(seg);
                
                ngx_buf_t buf = (ngx_buf_t) {
                        .pos = start,
                        .last = end,
                };
                
                ngx_int_t r = ngx_http_parse_request_line(&req, &buf);
                if (r == NGX_OK) {
                        printf("completed, NGX_OK\n");
                        break;
                } else if (r == NGX_AGAIN) {
                        printf("AGAIN, %d\n", i);
                        continue;
                } else {
                        printf("dont know what: %d\n", r);
                        break;
                }
        }
}

int main(void)
{
        test_full();
        test_seg();
        
        return 0;
}
